package chapter02.part03;

import chapter02.Employee;
import chapter02.FileUtil;

import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;

/**
 * 序列化机制 允许将任何对象写入到流中
 * 重要场景: 网络传输
 *
 * @author insight
 * @since 2021/8/13
 */
public class ObjectStreamTest {
    public static void main(String[] args) {
        Employee mugen = new Employee("mugen", 75000, 1987, 12, 15);
        Employee jin = new Employee("jin", 60000, 1986, 10, 1);
        Employee fuu = new Employee("fuu", 40000, 1990, 3, 15);
        // 设置共享对象
        // 对于这种复杂的对象网络 序列化采用的是使用序列号而不是内存地址(内存地址会改变)
        // 下面可以看到 序列号对重复读写的作用 类似缓存?
        mugen.setShare(fuu);
        jin.setShare(fuu);
        
        Employee[] staff = new Employee[3];

        staff[0] = fuu;
        staff[1] = mugen;
        staff[2] = jin;

        System.out.println(fuu.getSalary());

        // 保存
        try (ObjectOutputStream out = new ObjectOutputStream(
                FileUtil.getTestFileOutputStreamInstance())) {
            // 重复写 只会写一次
            out.writeObject(staff);
            out.writeObject(staff);
        } catch (IOException e) {
            e.printStackTrace();
        }
        
        // 加载
        try (ObjectInputStream in = new ObjectInputStream(
                FileUtil.getTestFileInputStreamInstance())) {
            // readObject() 底层使用反射 会生成新对象 按理说每次读取对象都不同
            Employee[] newStaff1 = (Employee[]) in.readObject();
            Employee[] newStaff2 = (Employee[]) in.readObject();

            // 可以看见多次读是一样的
            // false
            System.out.println(staff == newStaff1);
            // true
            System.out.println(newStaff1 == newStaff2);
            // 共享对象还是一样的
            System.out.println(newStaff1[1].getShare() == newStaff1[2].getShare());
            
            newStaff1[0].raiseSalary(100);
            
            for (Employee e : newStaff1) {
                System.out.println(e);
            }
        } catch (IOException | ClassNotFoundException e) {
            e.printStackTrace();
        }
    }
}